package com.iteaj.iot.builder;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ServiceLoaderUtil;
import com.iteaj.iot.*;
import com.iteaj.iot.business.ProtocolHandleFactory;
import com.iteaj.iot.event.FrameworkEventListener;
import com.iteaj.iot.handle.proxy.ProtocolHandleProxyMatcher;

import java.util.*;

public class IotBuilder {

    /**
     * 配置参数
     */
    private IotCoreProperties properties;

    private Set<ProtocolHandleProxyMatcher> proxyMatchers;

    /**
     * 监听器列表
     */
    private List<FrameworkEventListener> listeners;

    private DeviceManagerFactory deviceManagerFactory;

    protected IotBuilder(IotCoreProperties properties) {
        this.properties = properties;
        this.proxyMatchers = new HashSet<>();
        this.listeners = new ArrayList<>(8);
    }

    public IotBuilder(IotCoreProperties properties, DeviceManagerFactory deviceManagerFactory) {
        this.properties = properties;
        this.listeners = new ArrayList<>(8);
        this.deviceManagerFactory = deviceManagerFactory;
    }

    /**
     * 用默认的配置构建
     * @return
     */
    public static IotBuilder use() {
        return new IotBuilder(new IotCoreProperties());
    }

    /**
     * 自定义配置构建
     * @param properties
     * @return
     */
    public static IotBuilder use(IotCoreProperties properties) {
        return new IotBuilder(properties);
    }


    /**
     * 自定义配置构建
     * @param properties
     * @return
     */
    public static IotBuilder use(IotCoreProperties properties, DeviceManagerFactory managerFactory) {
        return new IotBuilder(properties, managerFactory);
    }

    /**
     * 注册监听器
     * @param listener
     * @return
     */
    public IotBuilder listener(FrameworkEventListener listener) {
        this.listeners.add(listener); return this;
    }

    /**
     * 注册监听器
     * @param listeners
     * @return
     */
    public IotBuilder listener(Collection<? extends FrameworkEventListener> listeners) {
        this.listeners.addAll(listeners); return this;
    }

    /**
     * 注册协议处理器代理
     * @param proxyMatcher
     * @return
     */
    public IotBuilder proxy(ProtocolHandleProxyMatcher proxyMatcher) {
        this.proxyMatchers.add(proxyMatcher);
        return this;
    }

    /**
     * 注册协议处理器代理
     * @param proxyMatchers
     * @return
     */
    public IotBuilder proxy(Collection<ProtocolHandleProxyMatcher> proxyMatchers) {
        this.proxyMatchers.addAll(proxyMatchers);
        return this;
    }

    /**
     * 注册协议处理器代理
     * @param proxyMatchers
     * @return
     */
    public IotBuilder proxy(ProtocolHandleProxyMatcher... proxyMatchers) {
        this.proxyMatchers.addAll(Arrays.asList(proxyMatchers));
        return this;
    }

    public FrameworkManager build() {
        IotThreadManager instance = IotThreadManager.instance();
        instance.start(properties);

        ComponentFactory componentFactory = DefaultComponentFactory.getInstance();
        componentFactory.start((Object) null);

        ProtocolHandleFactory handleFactory = new ProtocolHandleFactory(this.proxyMatchers);
        ProtocolTimeoutManager timeoutManager = new ProtocolTimeoutManager(handleFactory);
        timeoutManager.start(null);

        FrameworkManager frameworkManager = FrameworkManager.getInstance();
        frameworkManager.build(this.listeners, instance, componentFactory
                , handleFactory, timeoutManager, deviceManagerFactory);


        return frameworkManager;
    }
}
